#ifndef _VL_TERMINATOR__H_
#define _VL_TERMINATOR__H_

#include <functional>
#include "wrapper/tunnel_message.h"

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:08:44
 * 
 * 预声明管道类
 */
class BaseTunnel;

/**
 * @Author: CimZzz
 * @Date: 2022-07-15 12:04:44
 * 
 * 管道终端基类
 */
class Terminator {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:08:49
	 * 
	 * 接收来自管道消息的回调
	 * @param 1 管道消息指针
	 */
	using MessageCallback = std::function<void(const std::shared_ptr<TunnelMessage>&)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:09:42
	 * 
	 * 接收来自管道数据的回调
	 * @param 1 管道数据指针
	 */
	using DataCallback = std::function<void(const std::shared_ptr<TunnelData>&)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:13:58
	 * 
	 * 构造方法
	 */
	explicit Terminator();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 16:59:20
	 * 
	 * 析构函数
	 */
	~Terminator();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:10:43
	 * 
	 * 安装管道消息回调
	 * @param messageCallback 管道消息回调
	 */
	void setupMessageCallback(MessageCallback messageCallback);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:11:16
	 * 
	 * 安装管道数据回调
	 * @param dataCallback 管道数据回调
	 */
	void setupDataCallback(DataCallback dataCallback);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 15:44:43
	 * 
	 * 向指定管道输入数据
	 * @param tunnel 管道指针
	 * 
 	 * @return 返回管道指针
	 * 
	 * @note 如果当前管道不出于顶端, 将会一直遍历到顶部管道为止
	 */
	BaseTunnel* input(BaseTunnel* tunnel);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:12:50
	 * 
	 * 向指定管道输出数据
	 * @param tunnel 管道指针
	 * 
	 * @note 如果当前管道不出于底端, 将会一直遍历到底部管道为止
	 */
	void output(BaseTunnel* tunnel);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:02:33
	 * 
	 * 向管道传递数据
	 * @param data 数据指针
	 */
	void passData(const std::shared_ptr<TunnelData>& data);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 17:34:05
	 * 
	 * 销毁整个数据管道
	 */
	void destroyAll();

protected:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:21:15
	 * 
	 * 接收来自管道的消息
	 * 
	 * * 供管道调用
	 * 
	 * @param message 管道消息指针
	 */
	virtual void recvTunnelMessage(const std::shared_ptr<TunnelMessage>& message);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:07:24
	 * 
	 * 接收来自管道的数据
	 * 
	 * * 供管道调用
	 * 
	 * @param data 管道数据指针
	 */
	virtual void recvTunnelData(const std::shared_ptr<TunnelData>& data);

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:11:47
	 * 
	 * 数据流向枚举
	 */
	enum DataFlow {
		// 无可操作管道
		NoneDataFlow,
		// 输入管道
		InputDataFlow,
		// 输出管道
		OuputDataFlow
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:09:00
	 * 
	 * 声明管道为友元类
	 */
	friend class BaseTunnel;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:11:59
	 * 
	 * 管道消息回调
	 */
	MessageCallback messageCallback;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 14:12:08
	 * 
	 * 管道数据回调
	 */
	DataCallback dataCallback;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:12:16
	 * 
	 * 管道数据流向
	 */
	DataFlow dataFlow;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-15 12:11:17
	 * 
	 * 当前操作的管道
	 */
	BaseTunnel* operTunnel;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 16:57:37
	 * 
	 * 重置当前终端的管道
	 * 
	 * * 重置为无管道状态
	 */
	void resetTunnel();
};

}

#endif // _VL_TERMINATOR__H_
